// Study Swift EveryWhere
// duoba
// 2016.03.04

import UIKit

var str = "Hello, playground"

// 常量 & 变量
let a = 10
let b = "好"
let c = 3.1415926
let str1 = "nihao"
let str2 = "你好"
// 字符串的拼接
let str3 = str1 + str2

// 字符串转化
let str4 = "个苹果"
let str5 = "I have \(a)" + str4

// 数组
var shoppingList = ["water","paper","blue paint"]
print(shoppingList[1])
shoppingList[2] = "red paint"
print (shoppingList)

// 字典
var address = [
    "teddy":"shanghai",
    "andy":"beijing"
]
print (address["andy"])

//创建空数组和字典
let emptyArray = [String]()
let emptyDictionary = [String:Int]()

// 控制流
let individualScores = [75, 43, 103, 87, 12]
var teamScore = 0
for score in individualScores{
    if score > 50 {
        teamScore += 3
    }
    else{
        teamScore += 1
    }
}
print (teamScore)

// 可选值 (没懂)
var optionalString: String? = "Hello"
optionalString = nil

// if let 用法 (没懂)
var optionalName: String? = "TeddyLong"
var greeting = "Hello"
if let name = optionalName {
    greeting = "Hello, \(name)"
}

// Switch 用法
let vegetable = "red pepper"
switch vegetable {
    case "celery":
        let vegetableComment = "Add some raisins and make ants on a log."
    case "cucumber":
        let vegetableComment = "That would make a good tea sandwich"
    case let x where x.hasSuffix("pepper"):
        let vegetableComment = "Is it a spicy \(x)"
    default:
        let vegetableComment = "Everything is good"
}

// for-in 遍历字典
let interestingNumbers = [
    "Prime": [2,3,5,7,11,13],
    "Fibonacci": [1,1,2,3,5,8],
    "Square": [1,4,9,16,25]
]
var largest = 0
var largestType = ""
for (kind, numbers) in interestingNumbers {
    for number in numbers {
        if number > largest {
            largest = number
            largestType = kind
        }
    }
}
print (" \(largest): " + largestType)

// while的使用
var n = 2
while n < 100 {
    n = n * 2
}
print (n)

// 在循环中可以使用 ..< 表示范围， 这个是不包含上界，如果想包含则使用 ...
var firstForLoop = 0
for i in 0 ..< 4 {
    firstForLoop += i
}
print(firstForLoop)

var secondForLoop = 0
for i in 0 ... 4 {
    secondForLoop += i
}
print(secondForLoop)

// 函数和闭包, 使用func来声明一个函数，使用 -> 来指定函数返回值
func greet(name:String, day:String) -> String {
    return "Hello \(name), today is \(day)"
}
print (greet("Teddy", day: "2016/03/10"))

// 使用元组来返回多个值，该元组的元素可以用名称或者数字来表示
func calculateStatistics(scores:[Int]) -> (min:Int, max:Int, sum:Int) {
    var min = scores[0]
    var max = scores[0]
    var sum = 0
    for score in scores {
        if score > max {
            max = score
        }
        else if score < min {
            min = score
        }
        sum += score
    }
    return (min, max, sum)
}
let statistics = calculateStatistics([2,3,55,223,5,85])
statistics.max
statistics.sum
statistics.2

// 函数可以带有可变个数的参数, 这些参数在函数内表现为数组的形式
func sumOf(numbers:Int...) -> Int {
    var sum = 0
    for number in numbers {
        sum += number
    }
    return sum
}
print (sumOf(123,24,5,345,7665,756,7567567))
print (sumOf(123,245,4576,768,89,54,6,345,34,534,5,345,7665,756,567567))

// 函数的嵌套
func returnFifteen() -> Int {
    var y = 99
    func add() {
        y += 5
    }
    add()
    return y
}
print (returnFifteen())

// 函数可以作为另一个函数的返回值 (不懂)
func makeIncrementer() -> (Int -> Int) {
    func addOne(number: Int) -> Int {
        return 1 + number
    }
    return addOne
}
var increment = makeIncrementer()
increment(7)

// 函数也可以当做参数传入另一个函数 (不懂)
func hasAnyMatches(list: [Int], condition: Int -> Bool) -> Bool {
    for item in list {
        if condition(item) {
            return true
        }
    }
    return false
}
func lessThanTen(number: Int) -> Bool {
    return number < 10
}
var numbers = [20, 19, 7, 12]
hasAnyMatches(numbers, condition: lessThanTen)

// 对象和类
class Shape {
    var numberOfSides:Int = 0
    var name:String
    init(name:String) {
        self.name = name
    }
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}
var shape = Shape(name: "7")
shape.numberOfSides = 7
shape.simpleDescription()

// 继承父类
class Square:Shape {
    var sideLength: Double
    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 4
    }
    func area() -> Double {
        return sideLength * sideLength
    }
    override func simpleDescription() -> String {
        return "A square with sides of length \(sideLength)."
    }
}
var square = Square(sideLength: 4, name: "SmallSquare")
square.area()
square.simpleDescription()

// 类的get和set方法
// 注意EquilateralTriangle类的构造器执行了三步：
// 1.设置子类声明的属性值
// 2.调用父类的构造器
// 3.改变父类定义的属性值。其他的工作比如调用方法、getters和setters也可以在这个阶段完成
class EquilateralTriangle:Shape {
    var sideLength: Double = 0
    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 3
    }
    var perimeter: Double {
        get{
            return 3.0 * sideLength
        }
        set{
            sideLength = newValue / 3.0
        }
    }
    override func simpleDescription() -> String {
        return "An equilateral triagle with sides of length \(sideLength)."
    }
}
var triangle = EquilateralTriangle(sideLength: 3.2, name: "a triangle")
triangle.perimeter
triangle.perimeter = 9.9
triangle.sideLength

// 枚举 1
enum Rank: Int {
    case Ace = 1
    case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
    case Jack, Queen, King
    func simpleDescription() -> String {
        switch self {
        case .Ace:
            return "ace"
        case .Jack:
            return "jack"
        case .Queen:
            return "queen"
        case .King:
            return "king"
        default:
            return String(self.rawValue)
        }
    }
}
let king = Rank.King
let kingRawValue = king.rawValue
king.simpleDescription()

// 枚举 2
enum Suit {
    case Spades, Hearts, Diamonds, Clubs
    func simpleDescription() -> String {
        switch self {
        case .Spades:
            return "spades"
        case .Hearts:
            return "hearts"
        case .Diamonds:
            return "diamonds"
        case .Clubs:
            return "clubs"
        }
    }
    
}
let hearts = Suit.Hearts
let heartsDescription = hearts.simpleDescription()

// 结构体 1
struct Card {
    var rank: Rank
    var suit: Suit
    func simpleDescription() -> String {
        return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
    }
}
let threeOfSpades = Card(rank: .Three, suit: .Spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()

// 结构体 2
struct structFrame {
    var x : Float
    var y : Float
    var width : Float
    var height : Float
    var centerX : Float{
        get{
            return x + width/2
        }
        set{
            self.centerX = newValue
        }
    }
    var centerY :Float{
        get{
            return y + height/2
        }
        set{
            self.centerY = newValue
        }
    }
    init(x : Float, y : Float, width : Float, height : Float){
        self.x = x
        self.y = y
        self.width = width
        self.height = height
    }
    static func sayHello(){
        print("Hello")
    }
}
let frameOne : structFrame = structFrame.init(x: 0, y: 0, width: 100, height: 100)
structFrame.sayHello()

// 协议
protocol ExampleProtocol {
    var simpleDescription: String { get }
    mutating func adjust()
}

// 实现协议的类
class SimpleClass: ExampleProtocol {
    var simpleDescription: String = "A very simple class."
    var anotherProperty: Int = 7654
    func adjust() {
        simpleDescription += " Now 100% adjusted."
    }
}
var sc = SimpleClass()
sc.simpleDescription
sc.adjust()
sc.simpleDescription

// 实现协议的结构体
struct SimpleStructure: ExampleProtocol {
    var simpleDescription: String = "A simple structure"
    mutating func adjust() {
        simpleDescription += " (adjusted)"
    }
}
var scs = SimpleStructure()
scs.simpleDescription
scs.adjust()
scs.simpleDescription

// 泛型 (不懂)
enum OptioanalValue<T> {
    case None
}









